home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / PC / MOBITEX.ZIP / MOBITEX.C next >
C/C++ Source or Header  |  1997-03-14  |  23KB  |  621 lines

  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <dos.h>
  4. #include <math.h>
  5. #include <string.h>
  6.  
  7. /************************************************************************/
  8. /*                  GLOBAL VARIABLE DECLARATIONS                        */
  9. /************************************************************************/
  10. int lc=0;
  11. char ob[1000];  /* output buffer for packet before being sent to screen */
  12. int obp=0;    /* pointer to current position in array ob        */
  13. double dtt, odtt,ul,ll; /* variables used in clock tracking routine     */
  14.  
  15. FILE *out;    /* pointer to output file                 */
  16.  
  17. /* configuration parameter declaration to the defaults for RAM network  */
  18. static int verbose = 0; /* verbose mode parameter */
  19. static int cfs = 1;    /* system specific frame sync checking status      */
  20. static int frsync=0xB433;     /* system specific frame sync         */
  21. static int btsync=0xCCCC;    /* bit sync                             */
  22. static double brate = 8000.0;     /* Mobitex system baud rate         */
  23. static int bitscr = 1;           /* bit scrambling in use ?         */
  24. static int clocka = 1;           /* fine tune receive clock          */
  25. static int bitinv = 0;          /* bit inversion             */
  26. static int ramnet = 1;        /* ramnet flag - 1 means it's ram     */
  27. static int outfil = 1;          /* file output toggle                   */
  28. static int comport = 0x3f8;    /* serial port base address; set in main*/
  29. static int tempo=0;          /* maybe I should get a new compiler    */
  30.  
  31. /* data buffer for raw data coming in over serial port            */
  32. static unsigned int buflen= 15000;      /* length of data buffer          */
  33. static volatile unsigned int cpstn = 0; /* current position in buffer     */
  34. static unsigned int fdata[15001] ;      /* frequency data array           */
  35.  
  36. void interrupt (*oldfuncc) (); /* vector to old com port interrupt        */
  37.  
  38.  
  39. /************************************************************************/
  40. /*                 SERIAL PORT INTERRUPT HANDLER                        */
  41. /************************************************************************/
  42. /*                                this is serial com port interrupt       */
  43. /* we assume here that it only gets called when one of the status       */
  44. /* lines on the serial port changes (that's all you have hooked up).    */
  45. /* All this handler does is read the system timer (which increments     */
  46. /* every 840 nanoseconds) and stores it in the fdata array. The MSB     */
  47. /* is set to indicate whether the status line is zero. In this way      */
  48. /* the fdata array is continuously updated with the length and the      */
  49. /* length and polarity of each data pulse for further processing by     */
  50. /* the main program.                                */
  51. void interrupt com1int()
  52. {
  53.   static unsigned int d1,d2,ltick,tick,dtick;
  54.  
  55.   /* the system timer is a 16 bit counter whose value counts down     */
  56.   /* from 65535 to zero and repeats ad nauseum. For those who really  */
  57.   /* care, every time the count reaches zero the system timer           */
  58.   /* interrupt is called (remember that thing that gets called every  */
  59.   /* 55 milliseconds and does housekeeping such as checking the       */
  60.   /* keyboard).                                                       */
  61.   outportb (0x43, 0x00);       /* latch counter until we read it      */
  62.   d1 = inportb (0x40);         /* get low count                       */
  63.   d2 = inportb (0x40);         /* get high count                      */
  64.  
  65.   /* get difference between current, last counter reading             */
  66.   tick  = (d2 << 8) + d1;
  67.   dtick = ltick - tick;
  68.   ltick = tick;
  69.  
  70.   /* set MSB to reflect state of input line */
  71.   if ((inportb(comport + 6) & 0xF0) > 0) dtick = dtick | 0x8000;
  72.                   else dtick = dtick & 0x3fff;
  73.  
  74.   fdata[cpstn] = dtick;        /* put freq in fdata array             */
  75.   cpstn  ++;                   /* increment data buffer pointer       */
  76.   if (cpstn>buflen) cpstn=0;   /* make sure cpstn doesnt leave array  */
  77.  
  78.   d1 = inportb (comport + 2);   /* clear IIR                           */
  79.   d1 = inportb (comport + 5);   /* clear LSR                           */
  80.   d1 = inportb (comport + 6);   /* clear MSR                           */
  81.   d1 = inportb (comport);       /* clear RX                            */
  82.   outportb (0x20, 0x20);       /* this is the END OF INTERRUPT SIGNAL */
  83.                                /* "... that's all folks!!!!"          */
  84. }
  85.  
  86. /************************************************************************/
  87. /*                  SERIAL PORT INITIALIZATION                          */
  88. /************************************************************************/
  89. /* basic purpose: enable modem status interrupt and set serial port     */
  90. /*          output lines to supply power to interface             */
  91. void set8250 ()                /* sets up the 8250 UART               */
  92. {
  93.   static unsigned int t;
  94.   outportb (comport+3, 0x00);  /*  set IER on 0x03f9                  */
  95.   outportb (comport+1, 0x08);  /*  enable MODEM STATUS INTERRUPT      */
  96.   outportb (comport+4, 0x0a);  /*  push up RTS, DOWN DTR              */
  97.   t = inportb(comport + 5);    /*  clear LSR                          */
  98.   t = inportb(comport);        /*  clear RX                           */
  99.   t = inportb(comport + 6);    /*  clear MSR                          */
  100.   t = inportb(comport + 2);    /*  clear IID                          */
  101.   t = inportb(comport + 2);    /*  clear IID - again to make sure     */
  102. }
  103.  
  104. /************************************************************************/
  105. /*                    TIMER CHIP INITIALIZATION                         */
  106. /************************************************************************/
  107. /* purpose: make sure computer timekeeper is set up properly. This      */
  108. /*          routine probably isn't necessary - it's just an insurance   */
  109. /*        policy.                                                     */
  110. void set8253()                 /*  set up the 8253 timer chip         */
  111. {                              /* NOTE: ctr zero, the one we are using*/
  112.                                /*  is incremented every 840nSec, is   */
  113.                                /*  main system time keeper for dos    */
  114.   outportb (0x43, 0x34);       /* set ctr 0 to mode 2, binary         */
  115.   outportb (0x40, 0x00);       /* this gives us the max count         */
  116.   outportb (0x40, 0x00);
  117. }
  118.  
  119. /************************************************************************/
  120. /*          minor forward error correcting stuff stuff...               */
  121. /************************************************************************/
  122. /* do error correcting stuff */
  123.  
  124. /* matrix for block encoding */
  125. int h3 = 0xEC, h2 = 0xD3, h1 = 0xBA, h0 = 0x75;
  126.  
  127. /* returns the number of ones in the byte passed to routine */
  128. int ones(int h)
  129. {
  130.   static int i,nb;
  131.   nb = 0;
  132.   for (i=0; i<8; i++)
  133.   {
  134.     if ((h & 0x01) == 1) nb++;
  135.     h = h >> 1;
  136.   }
  137.   return(nb);
  138. }
  139.  
  140. /* returns number of ones in the integer passed to routine */
  141. int ones_int(int h)
  142. {
  143.   return(ones(h) + ones(h >> 8));
  144. }
  145.  
  146. /************************************************************************/
  147. /*          RUN THROUGH BLOCK FORWARD ERROR CORRECTION CODE             */
  148. /************************************************************************/
  149. /* PURPOSE:                                                           */
  150. /*       does FEC on the 8 data bits and 4 FEC bits passed to it in goi */
  151. /*       blert tries to check and correct errors... If the errors are   */
  152. /*       uncorrectable blert returns a 1 ; otherwise 0                  */
  153. /*       but don't read too much into this - two thirds of the time     */
  154. /*       random crap going into this routine will not generate the      */
  155. /*       uncorrectable error signal... Please Rely on the CRC check     */
  156. int blert(int *goi)
  157. {
  158.    static int dab,nb,bb,uce=0;
  159.  
  160.    uce = 0;  /* flag that indicates an uncorrectable error */
  161.  
  162.    /* calculate ecc bits from our current info bits */
  163.    dab = *goi >> 4;
  164.    nb  = (ones(dab & h3) & 0x01) << 3;
  165.    nb += (ones(dab & h2) & 0x01) << 2;
  166.    nb += (ones(dab & h1) & 0x01) << 1;
  167.    nb += (ones(dab & h0) & 0x01);
  168.  
  169.    /* get syndrome */
  170.    nb = nb ^ (*goi & 0x0f);
  171.  
  172.    if (ones(nb) > 0) uce = 1; else uce = 0;
  173.    /* if syndrome is not equal to zero try to correct the bad bit */
  174.    if (ones(nb) > 1)
  175.    {
  176.      if ((nb & 0x08) > 0) bb  = h3; else bb  = h3 ^ 0xff;
  177.      if ((nb & 0x04) > 0) bb &= h2; else bb &= h2 ^ 0xff;
  178.      if ((nb & 0x02) > 0) bb &= h1; else bb &= h1 ^ 0xff;
  179.      if ((nb & 0x01) > 0) bb &= h0; else bb &= h0 ^ 0xff;
  180.  
  181.      /* are we pointing to a single bit? if so we nailed the bastard */
  182.      if ( ones(bb) == 1) *goi = *goi ^ (bb<<4); else uce ++;
  183.    }
  184.    else *goi = *goi ^ nb;
  185.    /* single wrong bit in syndrome => error occured in FEC bits */
  186.  
  187.    return(uce);
  188. }
  189.  
  190. /************************************************************************/
  191. /*               BIT SCRAMBLING SEQUENCE GENERATOR                      */
  192. /************************************************************************/
  193. /* following is the pseudo-random bit scrambling generator.              */
  194. /* It's the output of a 9 stage linear-feedback shift register with taps */
  195. /* at position 5 and 9 XORed and fed back into the first stage.          */
  196. /* An input of less than zero resets the scrambler.                      */
  197. /* Otherwise it returns one bit at a time each time it is called         */
  198. int bs(int st)
  199. {
  200.   static int rs,ud;
  201.  
  202.   /* leave if system isn't supposed to use bit scrambling */
  203.   if (bitscr == 0) return(0);
  204.  
  205.   if (st < 0) rs = 0x1E;  /* inputs <0 reset scrambler */
  206.   else
  207.   {
  208.     if ( (rs & 0x01) > 0) ud=1; else ud = 0;
  209.     if ( (rs & 0x10) > 0) ud = ud ^ 0x01;
  210.     rs = rs >> 1;
  211.     if (ud > 0) rs = rs ^ 0x100;
  212.   }
  213.   return(ud);
  214. }
  215.  
  216. /************************************************************************/
  217. /*                       CRC GENERATING ROUTINE                         */
  218. /************************************************************************/
  219. /* CRC generator - passing a -1 to this routine resets it, otherwise */
  220. /* pass all 144 data bits in the mobitex data block to it (starting  */
  221. /* with byte 0, LSB bit). The returned value will then be the        */
  222. /* CRC value. Passing any other negative value just returns CRC.     */
  223. unsigned int crc(signed int gin)
  224. {
  225.   static unsigned int sr = 0x00,cr;
  226.  
  227.   if (gin >= 0)
  228.   {
  229.     if (gin == 1) cr = cr ^ sr;
  230.     if ((sr & 0x8000) != 0) sr = (sr << 1) ^ 0x0811; else sr = sr << 1;
  231.   }
  232.   else if (gin == -1)                     /* -1 resets the crc state */
  233.   {
  234.     sr = 0xF8E7;
  235.     cr = 0x2A5D;
  236.   }
  237.  
  238.   return(cr);
  239. }
  240.  
  241.  
  242. /**********************************************************************/
  243. /*          PROCESS RECEIVED 240 BIT MOBITEX DATA BLOCK               */
  244. /**********************************************************************/
  245. /* process MOBITEX data block */
  246. int barfrog()
  247. {
  248.   static int i,j,k,b,nerr,cb;
  249.   static unsigned int crcc=0x0000;
  250.   static int blob[30];
  251.   nerr = 0;
  252.  
  253.   /* process data block into 20 byte chunk stored in array blob */
  254.   crc(-1);            /* reset crc routine */
  255.   crcc = 0x0000;
  256.   for (i=0; i<20; i++)
  257.   {
  258.     /* uninterleave the data into b (holds 8 data bits + 4 FEC bits) */
  259.     b = 0;
  260.     for (j = 0; j<12; j++)
  261.     {
  262.       b = b << 1;
  263.       k = (j*20) + i;
  264.       if (ob[k] == 49) b ^= 0x01;
  265.     }
  266.  
  267.     /* run through error correction routine */
  268.     nerr+=blert(&b);
  269.  
  270.     /* spit out data bits to CRC routine - LSB data bit first... */
  271.     cb = b >> 4;
  272.     if (i < 18)
  273.     {
  274.       for (j=0; j<8; j++)
  275.       {
  276.     if ( (cb & 0x01) == 1) crc(1); else crc(0);
  277.     cb = cb >> 1;
  278.       }
  279.     }
  280.     else
  281.     {
  282.       crcc = (crcc << 8) ^ (cb & 0xff) ;
  283.     }
  284.  
  285.     /* store the byte in our wonderful wonderful array */
  286.     b = b >> 4;
  287.     blob[i] = b;
  288.   }
  289.  
  290.   /* at this point array BLOB holds the data; nerr gives the number  */
  291.   /* of errors detected by the FEC code ('corrected' errors count as */
  292.   /* one, uncorrectable count as 2); and crcc gives the received     */
  293.   /* CRC code. We use this info to decide if we got a good block     */
  294.  
  295.   /* if CRC is correct or nerr <15 we'll say it's a good block */
  296.   if ( (crc(-2) == crcc) | (nerr < 15) )
  297.   {
  298.     for (i=0; i<20; i++)
  299.     {
  300.       printf("%02X",blob[i]);
  301.       if (outfil) fprintf(out,"%02X",blob[i]);
  302.     }
  303.     if ( crc(-2) == crcc)
  304.     {
  305.       printf ("         ");
  306.       if (outfil) fprintf (out,"         ");
  307.     }
  308.     else
  309.     {
  310.       printf(" BAD CRC ");
  311.       if (outfil) fprintf(out," BAD CRC ");
  312.     }
  313.     for (i=0; i<20; i++) if (blob[i] > 31)
  314.     {
  315.       printf ("%c",blob[i]);
  316.       if (outfil) fprintf (out,"%c",blob[i]);
  317.     }
  318.     else
  319.     {
  320.       printf (".");
  321.       if (outfil) fprintf(out,".");
  322.     }
  323.     printf("\n");
  324.     if (outfil) fprintf(out,"\n");
  325.   }
  326.  
  327.   return(nerr);
  328. }
  329.  
  330. /************************************************************************/
  331. /*              FRAME SYNCHRONIZATION OF RAW BIT STREAM                 */
  332. /************************************************************************/
  333. /* this routine tries to achieve frame sync up in the raw bit stream      */
  334. int frame_sync(char gin)
  335. {
  336.   static int s1=0x0000,s2=0x0000;
  337.   static int cb1,cb2,bc=0,nbc=0,og,nu,bcb,fss = 0,fsb;
  338.  
  339.   fss = 0;
  340.   /* nbc is a bit counter for # of bits left to form into a data block */
  341.   if (nbc == 0)
  342.   {
  343.     /* nbc = 0 so we aren't trying to process a data block; instead try */
  344.     /* to sync up with incoming bit stream                              */
  345.  
  346.     /* keep sliding buffers up to date */
  347.     s1 = s1 << 1;
  348.     if ( (s2 & 0x8000) != 0) s1++;
  349.     s2 = s2 << 1;
  350.     if (gin == 49) s2++;
  351.  
  352.     /* check for sync */
  353.     fsb = ones_int(s1^btsync);
  354.     if (cfs) fsb += ones_int(s2^frsync);
  355.     /* if first two integers match up within a bit or two then     */
  356.     /* we've gotten frame sync                    */
  357.     if ( (fsb < (1+cfs)) && (bc == 0) )
  358.     {
  359.       if (verbose)
  360.       {
  361.     printf("SYSTEM FRAME SYNC %04X  ;",s2);
  362.     if (outfil) fprintf(out,"SYSTEM FRAME SYNC %04X  ;",s2);
  363.       }
  364.       bc = 25;
  365.     }
  366.  
  367.     /* bc is a bit counter used to pick off the two status bytes and  */
  368.     /* the FEC byte in the header.                                    */
  369.     if (bc > 0)
  370.     {
  371.       bc--;
  372.       if (bc == 0)
  373.       {
  374.     /* strip off control bytes, run them through FEC routine */
  375.     cb1 = (s1 & 0xff) << 4;
  376.     cb1 += (s2 >> 4) & 0xf;
  377.     cb2 = (s2 >> 4) & 0xff0;
  378.     cb2 += (s2 & 0xf);
  379.     bcb = blert(&cb1) + blert(&cb2);
  380.     if (bcb == 0) fss = 1;
  381.     if (verbose)
  382.     {
  383.       printf ("Control Bytes #1=%02X, #2=%02X",cb1>>4,cb2>>4);
  384.       if (outfil) fprintf (out,"Control Bytes #1=%02X, #2=%02X",
  385.                            cb1>>4,cb2>>4);
  386.       if (bcb != 0)
  387.       {
  388.         printf (" BAD Control Byte FEC");
  389.         if (outfil) fprintf (out," BAD Control Byte FEC");
  390.       }
  391.       printf("\n");
  392.       if (outfil) fprintf(out,"\n");
  393.     }
  394.  
  395.     /* for RAM network -                                            */
  396.     /*  control byte2 : bits 1 and 2 both 0 -> data block(s) follow */
  397.     /* otherwise just be adventurous and see if we get a valid block */
  398.     if (ramnet) { if ( (cb2 & 0x60) == 0) nbc = 1440; }
  399.             else nbc = 1440;
  400.     nu = 0;
  401.     bs(-1);
  402.       }
  403.     }
  404.   }
  405.   else
  406.   {
  407.     if (bs(1) == 1) og = gin ^ 0x01; else og = gin;
  408.     ob[nu] = og;
  409.     nu ++;
  410.     if (nu == 240)
  411.     {
  412.       nu = 0 ;
  413.       if (barfrog() < 15) nbc = 241; else nbc = 1;
  414.     }
  415.     nbc --;
  416.     if (nbc == 0)
  417.     {
  418.       printf ("\n");
  419.       if (outfil) fprintf(out,"\n");
  420.     }
  421.   }
  422.   return (fss);
  423. }
  424.  
  425. /************************************************************************/
  426. /*                    RECEIVE CLOCK TWEAKING ROUTINE                    */
  427. /************************************************************************/
  428. void check_clk(int i, int nbs)
  429. {
  430.   static int nt,ii,ndt,na=0;
  431.   static double a=0.0,avg,cvg;
  432.  
  433.   if (clocka)
  434.   {
  435.  
  436.     ii = i-1;
  437.     if (ii < 0) ii = buflen;
  438.     nt = 0;
  439.     ndt = 0;
  440.     while (ndt < (54-nbs) )
  441.     {
  442.       nt += fdata[ii];
  443.       ndt = 0.5 + (nt/odtt);
  444.       ii--;
  445.       if (ii < 0) ii = buflen;
  446.     }
  447.     cvg = (double) nt / ndt;
  448.  
  449.     /* update average if in roughly the right range */
  450.     if ( (cvg < ul) && (cvg > ll))
  451.     {
  452.       a = a + cvg;
  453.       na ++;
  454.       avg = a / (double) na;
  455.       dtt = avg;
  456.     }
  457.   }
  458. }
  459.  
  460. /************************************************************************/
  461. /*                         DISPLAY HELP SCREEN                          */
  462. /************************************************************************/
  463. void help()
  464. {
  465.   printf("\n  MOBITEX RECEIVING PROGRAM - Command line arguement summary\n");
  466.   printf("      (Defaults are set up for RAM Mobile Data's system.)\n\n");
  467.   printf("  /V:1        - print received system frame sync and control blocks\n");
  468.   printf("  /V:0        - don't show the above (DEFAULT)\n");
  469.   printf("  /CFS:1      - check system specific frame sync field (DEFAULT).\n");
  470.   printf("  /CFS:0      - Don't check it - useful for unknown systems.\n");
  471.   printf("  /FS:XXXX    - set system specific frame sync to HEX XXXX (DEFAULT B433)\n");
  472.   printf("  /SY:YYYY    - set bit sync to HEX YYYY (Default for base stations CCCC)\n");
  473.   printf("  /BR:Z       - Z is the Mobitex system's baud rate (Default = 8000).\n");
  474.   printf("  /BS:1       - System uses bit scrambling (DEFAULT)\n");
  475.   printf("  /BS:0       - system does not use bit scrambling\n");
  476.   printf("  /CA:1       - program attempts to fine tune receive clock (DEFAULT)\n");
  477.   printf("  /CA:0       - program does not attemp to fine tune receive clock.\n");
  478.   printf("  /BI:1       - Inverts incoming raw data.\n");
  479.   printf("  /BI:0       - don't invert incoming raw data (DEFAULT).\n");
  480.   printf("  /RN:1       - RAM only: control bytes determine if data blocks follow sync.\n");
  481.   printf("  /RN:0       - always try to decode data blocks regardless of control bytes.\n");
  482.   printf("  /OF:1       - Write data to output file (DEFAULT).\n");
  483.   printf("  /OF:0       - Don't write output data file.\n");
  484.   printf("  /COM:z      - set z = 1,2,3,4 to set com port you want to use.\n");
  485.   printf("\nSee text file for further details...");
  486.   printf(" press any key to continue...\n");
  487.   getch();
  488. }
  489.  
  490. /************************************************************************/
  491. /*                            MAIN ROUTINE                              */
  492. /************************************************************************/
  493. void main (int argc,char *argv[],char *env[])
  494. {
  495.   unsigned int n,i=0,j=0,k,l,nbs,imax=0;
  496.   int sport=1,irqv=0x0c;
  497.   char s=48,temp[20],yon[2][5]= {"OFF","ON"};
  498.   double pl,dt,exc=0.0,clk=0.0,xct;
  499.  
  500.   /* process command line arguements */
  501.   for (n=1; n<argc; n++)
  502.   {
  503.     strcpy(temp,argv[n]);
  504.     strupr(temp);
  505.     j+=sscanf(temp,"/FS:%X",&frsync);
  506.     j+=sscanf(temp,"/SY:%X",&btsync);
  507.     j+=sscanf(temp,"/V:%i",&verbose);
  508.     j+=sscanf(temp,"/CFS:%i",&cfs);
  509.     j+=sscanf(temp,"/BR:%g",&brate);
  510.     j+=sscanf(temp,"/BS:%i",&bitscr);
  511.     j+=sscanf(temp,"/CA:%i",&clocka);
  512.     j+=sscanf(temp,"/BI:%i",&bitinv);
  513.     j+=sscanf(temp,"/RN:%i",&ramnet);
  514.     j+=sscanf(temp,"/OF:%i",&outfil);
  515.     j+=sscanf(temp,"/COM:%i",&sport);
  516.     if (temp[1] == 'H') j=30;
  517.   }
  518.  
  519.   if ( (j+1) != argc) help();
  520.   printf ("\n\nProgram Options set as follows: \n");
  521.           printf ("Baud Rate        : %g baud\n",brate);
  522.           printf ("Frame sync       : %04X\n",frsync);
  523.           printf ("Bit sync         : %04X\n",btsync);
  524.   cfs    &= 0x01; printf ("Check frame sync : %s\n",yon[cfs]);
  525.   verbose&= 0x01; printf ("Verbose mode     : %s\n",yon[verbose]);
  526.   bitscr &= 0x01; printf ("Bit scrambling   : %s\n",yon[bitscr]);
  527.   clocka &= 0x01; printf ("Fine tune clock  : %s\n",yon[clocka]);
  528.   bitinv &= 0x01; printf ("Bit Inversion    : %s\n",yon[bitinv]);
  529.   ramnet &= 0x01; printf ("RAM network mode : %s\n",yon[ramnet]);
  530.   outfil &= 0x01; printf ("Output file echo : %s\n",yon[outfil]);
  531.   sport  &= 0x03; printf ("Running  on  COM%i\n\n",sport);
  532.  
  533.   if (outfil)
  534.   {
  535.     strcpy (temp,"MOBYDAXXXXXX");
  536.     mktemp(temp);
  537.     printf("\nfilename where screen display will be echoed : %s\n\n",temp);
  538.     out = fopen(temp,"wt");
  539.   }
  540.  
  541.   printf ("Press any key to stop program...\n\n");
  542.  
  543.   /* dtt is the number of expected clock ticks per bit                 */
  544.   dtt =  1.0/(brate*839.22e-9);      /* this will be the updated clock */
  545.   odtt = dtt;                              /* this oddt is not updated */
  546.   /* following give the range over which the the clock can be adjusted */
  547.   ul = odtt + 1.0;
  548.   ll = odtt - 1.0;
  549.  
  550.   /* set up serial port and related parameters                          */
  551.   n = inportb (0x21);
  552.   if ( (sport == 1) | (sport == 3))
  553.   {
  554.     irqv = 0x0c;
  555.     oldfuncc = getvect(irqv);    /* save COM  Vector                    */
  556.     setvect (irqv, com1int);     /* Capture COM  vector                 */
  557.     outportb(0x21, n & 0xef);
  558.     if (sport == 1) comport = 0x3f8; else comport = 0x3e8;
  559.   }
  560.   else
  561.   {
  562.     irqv = 0x0b;
  563.     oldfuncc = getvect(irqv);    /* save COM  Vector                    */
  564.     setvect (irqv, com1int);     /* Capture COM  vector                 */
  565.     outportb(0x21, n & 0xf7);
  566.     if (sport == 2) comport = 0x2f8; else comport = 0x2e8;
  567.   }
  568.  
  569.   set8253();                   /* set up 8253 timer chip              */
  570.  
  571.   set8250();                   /* set up 8250 UART                    */
  572.  
  573.   while ( (cpstn < 3) & (kbhit() == 0) );
  574.   if (cpstn < 3)
  575.   printf("HEY - no data seems to be coming in over your interface.\n\n");
  576.   else
  577.   printf("Interface seems to work properly...\n\n");
  578.  
  579.   /* main process routine - keeps on going until any key was hit      */
  580.   while (kbhit() == 0)
  581.   {
  582.    if (i != cpstn)
  583.    {
  584.     if  ( ( fdata[i] & 0x8000) != 0) s = 48; else s = 49;
  585.     s = s ^ bitinv;
  586.  
  587.     /* add in new number of cycles to clock  */
  588.     clk += (fdata[i] & 0x7fff);
  589.     xct = exc + 0.5 * dtt;  /* exc is current boundary */
  590.     nbs = 0;
  591.     while ( clk >= xct )
  592.     {
  593.       /* if frame_sync returns a 1 it means the last 56 bits were the sync */
  594.       /* frame_sync(s); */
  595.       nbs ++;
  596.       if (frame_sync(s) == 1) check_clk(i,nbs);
  597.       clk = clk - dtt;
  598.     }
  599.     /* clk now holds new boundary position. update exc slowly... */
  600.     /* 0.005 sucks; 0.02 better; 0.06 mayber even better; 0.05 seems pretty good */
  601.     exc = exc + 0.050*(clk - exc);
  602.  
  603.     i++;
  604.     if( i >buflen) i = 0;
  605.  
  606.     if ( ((cpstn - i) > imax) && (cpstn > i)) imax = cpstn - i;
  607.    }
  608.  
  609.   }
  610.  
  611.   /* shutdown */
  612.   outportb (0x21, n);          /* disable IRQ4 interrupt              */
  613.   setvect (irqv, oldfuncc);    /* restore old COM1 Vector             */
  614.  
  615.   printf (" %i\n",imax);
  616.   if (outfil) fclose(out);
  617. }
  618.  
  619. /*                                end of post                         */
  620.  
  621.